#!/usr/bin/python3
# Copyright 2021 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_load_texture_border_functions_table.py:
#  Code generation for the load texture border function tables used for texture formats. These mappings are
#  not renderer specific. The mappings are done from the GL internal format, to the ANGLE format ID.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
#

import json, sys

sys.path.append('../..')
import angle_format

template = """// GENERATED FILE - DO NOT EDIT.
// Generated by gen_load_texture_border_functions_table.py using data from load_texture_border_functions_data.json
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// load_texture_border_functions_table":
//   Contains the LoadTextureBorderFunctionMap for texture_format_util.h
//

#include "libANGLE/renderer/load_texture_border_functions_table.h"
#include "image_util/loadtextureborder.h"

using namespace rx;

namespace angle
{{

namespace
{{

// ES3 texture border color loading functions vary based on:
//    - the GL internal format (supplied to glTex*Image*D)
//    - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
//    device's capabilities)
// This map type determines which loading function to use, based on these two parameters.
// This map only contains formats which need to reorder border color channel explictly.

{load_functions_data}}}  // namespace

LoadTextureBorderFunctionMap GetLoadTextureBorderFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
{{
    switch ({internal_format})
    {{
{switch_data}
        default:
            // Use LoadToNative for any format that doesn't reorder channels.
            return DefaultLoadFunction;
    }}

}}  // GetLoadTextureBorderFunctionsMap

}}  // namespace angle
"""

internal_format_param = 'internalFormat'
angle_format_param = 'angleFormat'
angle_format_unknown = 'NONE'


def load_functions_name(internal_format, angle_format):
    return internal_format[3:] + "_to_" + angle_format


def get_load_func(func_name, load_function):
    snippet = "LoadTextureBorderFunctionInfo " + func_name + "()\n"
    snippet += "{\n"
    snippet += "    return LoadTextureBorderFunctionInfo(" + load_function + ");\n"
    snippet += "}\n"
    snippet += "\n"

    return snippet


def parse_json(json_data):
    table_data = ''
    load_functions_data = ''
    load_functions_data += get_load_func('DefaultLoadFunction', 'LoadToNative')
    for internal_format, angle_format_func in sorted(json_data["map"].items()):

        s = '        '

        table_data += s + 'case ' + internal_format + ':\n'

        do_switch = len(angle_format_func) > 1 or list(
            angle_format_func)[0] != angle_format_unknown

        if do_switch:
            table_data += s + '{\n'
            s += '    '
            table_data += s + 'switch (' + angle_format_param + ')\n'
            table_data += s + '{\n'
            s += '    '

            for angle_format, load_function in sorted(angle_format_func.items()):
                func_name = load_functions_name(internal_format, angle_format)
                # Main case statements
                table_data += s + 'case FormatID::' + angle_format + ':\n'
                table_data += s + '    return ' + func_name + ';\n'

                load_functions_data += get_load_func(func_name, load_function)

        if do_switch:
            table_data += s + 'default:\n'
            table_data += s + '    return DefaultLoadFunction;\n'

        if do_switch:
            s = s[4:]
            table_data += s + '}\n'
            s = s[4:]
            table_data += s + '}\n'

    return table_data, load_functions_data


def main():

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['angle_format.py', 'load_texture_border_functions_data.json']
        outputs = ['load_texture_border_functions_table_autogen.cpp']

        if sys.argv[1] == 'inputs':
            print(','.join(inputs))
        elif sys.argv[1] == 'outputs':
            print(','.join(outputs))
        else:
            print('Invalid script parameters')
            return 1
        return 0

    json_data = angle_format.load_json('load_texture_border_functions_data.json')

    switch_data, load_functions_data = parse_json(json_data)
    output = template.format(
        internal_format=internal_format_param,
        angle_format=angle_format_param,
        switch_data=switch_data,
        load_functions_data=load_functions_data)

    with open('load_texture_border_functions_table_autogen.cpp', 'wt') as out_file:
        out_file.write(output)
        out_file.close()
    return 0


if __name__ == '__main__':
    sys.exit(main())
